package com.graduation.alien_yuan.smartmusicplayer;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.SeekBar;
import android.widget.TextView;

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.ChartTouchListener;
import com.github.mikephil.charting.listener.OnChartGestureListener;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.graduation.alien_yuan.smartmusicplayer.bean.Spectrum;
import com.graduation.alien_yuan.smartmusicplayer.database.User;
import com.graduation.alien_yuan.smartmusicplayer.utils.LogUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class ListeningTestActivity extends AppCompatActivity implements OnChartGestureListener, OnChartValueSelectedListener {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listening_test);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setVisibility(View.GONE);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        initUI();
        initAudioTrack();
    }

    private LineChart mChart;
    private AudioTrackManager audioTM;
    private boolean isPlaySound;
    private int Hz=1000;
    private Thread thread;
    private void initAudioTrack(){
        audioTM=new AudioTrackManager();
        audioTM.setVolume(100f);
//        startPlay(Hz);
    }


    private ImageAdapter imageAdapter;
    private Gallery gallery;

    private void initUI(){

        gallery = (Gallery) findViewById(R.id.gallery);
        imageAdapter = new ImageAdapter(this);
        gallery.setAdapter(imageAdapter);
        gallery.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @SuppressLint("NewApi")
            @Override
            public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
                SeekBar seekBar = (SeekBar)v.findViewById(R.id.mySeekBar);
                seekBar.setProgress((int)(audioTM.getVolume()*seekBar.getMax()));
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {

            }
        });
        mChart = (LineChart)findViewById(R.id.line_chart);
//        initChart(mChart, getTestData(10, 100));
    }


    private void initChart(LineChart mChart,LineData data){
        mChart.setOnChartGestureListener(this);
        mChart.setOnChartValueSelectedListener(this);
        mChart.setDrawGridBackground(false);
        // no description text
        mChart.setDescription("description:--");
        mChart.setNoDataTextDescription("You need to provide data for the chart.");
        // enable touch gestures
        mChart.setTouchEnabled(true);


        // enable scaling and dragging
        mChart.setDragEnabled(false);
        mChart.setScaleEnabled(false);
//         mChart.setScaleXEnabled(true);
//         mChart.setScaleYEnabled(true);

        // if disabled, scaling can be done on x- and y-axis separately
        mChart.setPinchZoom(true);

        // set an alternative background color
        // mChart.setBackgroundColor(Color.GRAY);

        // create a custom MarkerView (extend MarkerView) and specify the layout
        // to use for it
//        MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);

        // set the marker to the chart
//        mChart.setMarkerView(mv);

        // x-axis limit line
        LimitLine llXAxis = new LimitLine(10f, "Index 10");
        llXAxis.setLineWidth(4f);
        llXAxis.enableDashedLine(10f, 10f, 0f);
        llXAxis.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
        llXAxis.setTextSize(10f);

        XAxis xAxis = mChart.getXAxis();
        xAxis.setTextColor(Color.WHITE);
        xAxis.setLabelsToSkip(0);
        //xAxis.setValueFormatter(new MyCustomXAxisValueFormatter());
        //xAxis.addLimitLine(llXAxis); // add x-axis limit line

//        Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf");

//        LimitLine ll1 = new LimitLine(130f, "Upper Limit");
//        ll1.setLineWidth(4f);
//        ll1.enableDashedLine(10f, 10f, 0f);
//        ll1.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
//        ll1.setTextSize(10f);
////        ll1.setTypeface(tf);
//
//        LimitLine ll2 = new LimitLine(-30f, "Lower Limit");
//        ll2.setLineWidth(4f);
//        ll2.enableDashedLine(10f, 10f, 0f);
//        ll2.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
//        ll2.setTextSize(10f);
//        ll2.setTypeface(tf);

        YAxis leftAxis = mChart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
//        leftAxis.addLimitLine(ll1);
//        leftAxis.addLimitLine(ll2);
        leftAxis.setAxisMaxValue(220f);
        leftAxis.setAxisMinValue(-50f);
        leftAxis.setTextColor(Color.WHITE);
        //leftAxis.setYOffset(20f);
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        leftAxis.setDrawZeroLine(false);

        // limit lines are drawn behind data (and not on top)
        leftAxis.setDrawLimitLinesBehindData(true);

        mChart.getAxisRight().setEnabled(false);

        //mChart.getViewPortHandler().setMaximumScaleY(2f);
        //mChart.getViewPortHandler().setMaximumScaleX(2f);

        mChart.setData(data);

//        mChart.setVisibleXRange(20);
//        mChart.setVisibleYRange(20f, AxisDependency.LEFT);
//        mChart.centerViewTo(20, 50, AxisDependency.LEFT);

        mChart.animateX(1, Easing.EasingOption.EaseInOutQuart);
        mChart.animate();
//        mChart.invalidate();

        // get the legend (only possible after setting data)
        Legend l = mChart.getLegend();

        // modify the legend ...
        // l.setPosition(LegendPosition.LEFT_OF_CHART);
        l.setForm(Legend.LegendForm.LINE);

        // // dont forget to refresh the drawing
        // mChart.invalidate();
    }


    private LineData getTestData(int[] freqs,HashMap<Integer,Float> freqMap) {

        final String[] strings = {"100","200","400","600","1K","3K","6K","12K","14K","16K"};
        ArrayList<String> xVals = new ArrayList<String>();
        for (int i = 0; i < strings.length; i++) {
            xVals.add((strings[i]) + "");
        }

        ArrayList<Entry> yVals = new ArrayList<Entry>();

        for (int i = 0; i < freqMap.size(); i++) {

            float val = freqMap.get(freqs[i])*150f;
            // ((mult *
            // 0.1) / 10);
            yVals.add(new Entry(val, i));
        }

        // create a dataset and give it a type
        LineDataSet set1 = new LineDataSet(yVals,"幅度");
        // set1.setFillAlpha(110);
        // set1.setFillColor(Color.RED);

        // set the line to be drawn like this "- - - - - -"
//        set1.enableDashedLine(10f, 5f, 0f);
//        set1.enableDashedHighlightLine(10f, 5f, 0f);
        set1.setColor(Color.WHITE);
        set1.setCircleColor(Color.WHITE);
        set1.setLineWidth(1f);
        set1.setCircleRadius(3f);
        set1.setDrawCircles(false);
        set1.setDrawCircleHole(false);
        set1.setValueTextSize(9f);
        set1.setValueTextColor(Color.WHITE);
        Drawable drawable = ContextCompat.getDrawable(this, R.drawable.fade_read);
        set1.setFillDrawable(drawable);
        set1.setDrawFilled(true);
        set1.setDrawCubic(true);

        ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
        dataSets.add(set1); // add the datasets

        // create a data object with the datasets
        LineData data = new LineData(xVals, dataSets);

        // set data
        return data;
    }

    @Override
    protected void onDestroy() {
        Spectrum spectrum = new Spectrum();
        ArrayList<Spectrum.SpectrumEntity> spectrumEntities = new ArrayList<>();
        HashMap<Integer,Float> hashMap = imageAdapter.getFreqVolMap();
        Iterator iterator = hashMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry entry = (Map.Entry)iterator.next();
            Spectrum.SpectrumEntity spectrumEntity = new Spectrum.SpectrumEntity();
            spectrumEntity.setFrequency(entry.getKey()+"");
            spectrumEntity.setAmplitude(entry.getValue()+"");
        }
        spectrum.setSpectrum(spectrumEntities);
        User.saveUserLog("id","register at","name","email",spectrum.toString());
        super.onDestroy();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode==KeyEvent.KEYCODE_BACK){
            isPlaySound=false;
            this.finish();
        }
        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
            audioTM.setVolume(AudioManager.STREAM_MUSIC);
        }
        return super.onKeyDown(keyCode, event);
    }


    public class ImageAdapter extends BaseAdapter {

        private Context mContext;
        private HashMap<Integer,Float> freqVolMap;
        public  final int[] frequencies = {100 , 200, 400, 600, 1000, 3000, 6000, 12000, 14000, 16000};
        public ImageAdapter(Context context) {
            mContext = context;
            freqVolMap = new HashMap<>();
            for (int freq:frequencies) {
                freqVolMap.put(freq,0f);
            }
        }

        public HashMap<Integer,Float> getFreqVolMap(){
            return freqVolMap;
        }
        public int[] getFrequencies(){
            return frequencies;
        }

        public int getCount() {
            return frequencies.length;
        }

        public Object getItem(int position) {
            return frequencies[position];
        }

        public long getItemId(int position) {
            return position;
        }

        @SuppressLint("NewApi")
        public View getView(final int position, View convertView, ViewGroup parent) {
            final ViewHolder viewHolder;
            if (convertView == null){
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_frequency_card, parent, false);
                convertView.setScaleX(0.8f);
                convertView.setScaleY(0.8f);
                viewHolder = new ViewHolder();
                viewHolder.cutButton = (Button)convertView.findViewById(R.id.item_frequency_card_cut_bt);
                viewHolder.addButton = (Button)convertView.findViewById(R.id.item_frequency_card_add_bt);
                viewHolder.playButton = (Button)convertView.findViewById(R.id.item_frequency_card_play_bt);
                viewHolder.seekBar = (SeekBar)convertView.findViewById(R.id.mySeekBar);
                viewHolder.freTextView = (TextView)convertView.findViewById(R.id.item_frequency_card_fre_tv);
                convertView.setTag(viewHolder);
            }else {
                viewHolder = (ViewHolder)convertView.getTag();
            }

            viewHolder.freTextView.setText(frequencies[position] + "Hz");
            viewHolder.addButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    audioTM.addVolum();
                    freqVolMap.put(frequencies[position], audioTM.getVolume());
                    startPlay(frequencies[position]);
                    viewHolder.seekBar.setProgress((int) (audioTM.getVolume() * viewHolder.seekBar.getMax()));
                    initChart(mChart, getTestData(frequencies, freqVolMap));
                }
            });
            viewHolder.cutButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    audioTM.cutVolum();
                    freqVolMap.put(frequencies[position], audioTM.getVolume());
                    startPlay(frequencies[position]);
                    viewHolder.seekBar.setProgress((int) (audioTM.getVolume() * viewHolder.seekBar.getMax()));
                    initChart(mChart, getTestData(frequencies, freqVolMap));
                }
            });
            viewHolder.playButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    freqVolMap.put(frequencies[position], audioTM.getVolume());
                    startPlay(frequencies[position]);
                    viewHolder.seekBar.setProgress((int) (audioTM.getVolume() * viewHolder.seekBar.getMax()));
                    initChart(mChart, getTestData(frequencies, freqVolMap));
                }
            });

            viewHolder.seekBar.setProgress((int) (audioTM.getVolume() * viewHolder.seekBar.getMax()));
            viewHolder.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                    float vol=(float)(seekBar.getProgress())/(float)(seekBar.getMax());
                    audioTM.setVolume(vol);//设置音量
                    freqVolMap.put(frequencies[position], audioTM.getVolume());
                }
            });

            return convertView;
        }

        public class ViewHolder{
            Button cutButton;
            Button addButton;
            Button playButton;
            SeekBar seekBar;
            TextView freTextView;
        }
    }

    public void startPlay(int hz){
        audioTM.stop();
        audioTM.start(hz);
        thread=new Thread(new Runnable() {
            @Override
            public void run() {
                audioTM.play();
            }
        });
        isPlaySound=true;
        thread.start();
    }



    @Override
    public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        LogUtils.d("onChartGestureStart:"+me.getAction()+"  "+lastPerformedGesture.name());

    }

    @Override
    public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

        LogUtils.d("onChartGestureStart:"+me.getAction()+"  "+lastPerformedGesture.name());

        if(lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP){
            mChart.highlightValues(null); // or highlightTouch(null) for callback to onNothingSelected(...)
        }
    }

    @Override
    public void onChartLongPressed(MotionEvent me) {

    }

    @Override
    public void onChartDoubleTapped(MotionEvent me) {

    }

    @Override
    public void onChartSingleTapped(MotionEvent me) {

    }

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {

    }

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {

    }

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {

    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {

    }

    @Override
    public void onNothingSelected() {

    }


}
